using System;
using System.Collections.Generic;

using IBatisNet.DataMapper;

using log4net;

using GymManager.Exception;
using GymManager.Persistence.VO;

namespace GymManager.Persistence.DAO
{
    /// <summary>
    /// Class responsible by getting information from database about monthly fee
    /// </summary>
    public class MonthlyFeeDAO
    {
        // logger instance
        private ILog _logManager = LogManager.GetLogger(typeof(MonthlyFeeDAO));

        /// <summary>
        /// Method responsible by getting the most recent monthly fee beloging to an specific student
        /// </summary>
        /// <param name="Int32">student identifier</param>
        /// <returns>MonthlyFee - most recent monthly fee belonging to an specific student</returns>
        /// <see cref="GymManager.Exception.Persistence"/>
        public MonthlyFee findMostRecentByStudent(Int32 studentId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // most recent monthly fee
            MonthlyFee mostRecentMonthlyFee = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                mostRecentMonthlyFee = ibatisMapper.QueryForObject<MonthlyFee>("MonthlyFee.findMostRecentByStudent", studentId);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving monthly fee information", ex);
                throw new PersistenceException("Error while retrieving monthy fee information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return mostRecentMonthlyFee;
        }

        /// <summary>
        /// Method responsible by finding monthly fees associated to some 
        /// student in given year
        /// </summary>
        /// <param name="Int32"> student identifier </param>
        /// <param name="Int32"> monthly fee base year </param>
        /// <returns>IList - list of all monthly fee matching with the criteria </returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public IList<MonthlyFee> findByStudentAndYear(Int32 studentId, Int32 monthlyFeeBaseYear)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // list of monthly fee
            IList<MonthlyFee> monthlyFeeList = null;

            try
            {
                // structure to be used as filter
                IDictionary<String, Int32> filterDictionary = new Dictionary<String, Int32>();
                filterDictionary.Add("BaseYear", monthlyFeeBaseYear);
                filterDictionary.Add("StudentId", studentId);

                ISqlMapper ibatisMapper = DAOManager.getInstance();
                monthlyFeeList = ibatisMapper.QueryForList<MonthlyFee>("MonthlyFee.findByStudentAndYear", filterDictionary);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving monthly fee information", ex);
                throw new PersistenceException("Error while retrieving monthy fee information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return monthlyFeeList;
        }

        /// <summary>
        /// Method responsible by adding a new monthly fee to database
        /// </summary>
        /// <param name="MonthlyFee">monthly fee information to be saved</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void create(MonthlyFee monthlyFeeVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Insert("MonthlyFee.insert", monthlyFeeVO);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while saving monthly fee information", ex);
                throw new PersistenceException("Error while saving monthly fee information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by removing a monthly fee from database
        /// </summary>
        /// <param name="Int32">monthly fee identifier</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void remove(Int32 monthlyFeeId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Delete("MonthlyFee.delete", monthlyFeeId);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while removing monthly fee information", ex);
                throw new PersistenceException("Error while removing monthly fee  information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by marking as paid the student's monthly fee.
        /// </summary>
        /// <param name="IList">monthly fee id list</param>
        /// <param name="Int32">user identifier who received the monthly fee payment</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void updateMonthlyFeeListAsPaid(IList<Int32> monthlyFeeIdList, Int32 receiverUserId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                // generate in clause element
                String inClause = String.Empty;
                foreach (Int32 monthlyFeeId in monthlyFeeIdList)
                {
                    inClause += monthlyFeeId + ",";
                }
                inClause = "(" + inClause.Substring(0, inClause.Length - 1) + ")";

                // structure to be used as filter
                IDictionary<String, Object> filterDictionary = new Dictionary<String, Object>();
                filterDictionary.Add("MonthlyFeeIdList", inClause);
                filterDictionary.Add("ReceiverUserId", receiverUserId);

                // updating information about monthly fee
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Update("MonthlyFee.updateMonthlyFeeAsPaid", filterDictionary);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving monthly fee information", ex);
                throw new PersistenceException("Error while retrieving monthly fee information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by getting all pending monthly fees associated to a given student.
        /// </summary>
        /// <param name="Int32">student identifier</param>
        /// <returns>IList - list of all monthly fee matching with the criteria </returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public IList<MonthlyFee> findPendingsByStudent(Int32 studentId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // list of monthly fee
            IList<MonthlyFee> monthlyFeeList = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                monthlyFeeList = ibatisMapper.QueryForList<MonthlyFee>("MonthlyFee.findPendingsByStudent", studentId);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving monthly fee information", ex);
                throw new PersistenceException("Error while retrieving monthy fee information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return monthlyFeeList;
        }
    }
}
